package io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * IO流
 * 
 * OutputStream		字节输出流
 * java.io.OutputStream 抽象类是表示字节输出流的所有类的超类，将指定的字节信息写出到目的地
 * 
 * public void close()								关闭此输出流并释放与此流相关联的任何系统资源
 * public void flush()								刷新此输出流并强制任何缓冲的输出字节被写出
 * public void write(byte[] b)						将 b.length字节从指定的字节数组写入此输出流
 * public void write(byte[] b, int off, int len)	从指定的字节数组写入 len字节，从偏移量 off开始输出到此输出流
 * public abstract void write(int b)				将指定的字节输出流
 * 
 * 
 * 
 * FileOutputStream类		文件输出流，是OutputStream的子类，用于将数据写入文件中
 * 当文件不存在时会创建该文件（前提是文件的路径存在，否则会抛出异常）
 * 构造方法
 * public FileOutputStream(File file)					创建文件输出流以写入由指定的 File对象表示的文件
 * public FileOutputStream(File file, boolean append)	参数append为true表示追加数据，为false表示清空原有数据
 * public FileOutputStream(String name)					创建文件输出流以指定的名称写入文件
 * public FileOutputStream(String name, boolean append)
 * 								参数append为true表示追加数据，为false表示清空原有数据
 * 创建一个流对象时，必须传入一个文件路径
 * 该路径下，如果没有这个文件，会创建该文件
 * 如果有这个文件，会清空这个文件的数据
 * 
 * write(int b)							每次可以写出一个字节数据，即int值对应的二进制的“低八位”
 * write(byte[] b)						每次可以写出数组中的数据
 * write(byte[] b, int off, int len)	每次写出从off索引开始，len个字节
 * 
 * 写出换行，Windows系统里，换行符号是 \r\n
 * 
 * 
 * 
 * InputStream		字节输入流
 * java.io.InputStream 抽象类是表示字节输入流的所有类的超类，可以读取字节信息到内存中
 * 
 * public void close()					关闭此输入流并释放与此流相关联的任何系统资源
 * public abstract int read()			从输入流读取数据的下一个字节
 * public int read(byte[] b)			从输入流中读取一些字节数，并将它们存储到字节数组 b中
 * 
 * 
 * 
 * FileInputStream类			是文件输入流，从文件中读取字节
 *  
 * 构造方法
 * FileInputStream(File file)		通过打开与实际文件的连接来创建一个 FileInputStream ，该文件由文件系统中的 File对象file命名
 * FileInputStream(String name)		通过打开与实际文件的连接来创建一个 FileInputStream ，该文件由文件系统中的路径名name命名
 * 创建一个流对象时，必须传入一个文件路径。该路径下，如果没有该文件,会抛出 FileNotFoundException
 *  
 * read()						每次可以读取一个字节的数据，提升为int类型，读取到文件末尾，返回 -1
 * read(byte[] b)				每次读取b的长度个字节到数组中，返回读取到的有效字节个数，读 取到末尾时，返回 -1
 *  
 *  
 *  
 * 流的关闭原则：先开后关，后开先关
 *  
 *  
 *  
 * Reader				字符输入流
 * public void close()				关闭此流并释放与此流相关联的任何系统资源
 * public int read()				从输入流读取一个字符
 * public int read(char[] cbuf)		从输入流中读取一些字符，并将它们存储到字符数组 cbuf中
 *  
 *  
 *  
 * FileReader类
 * java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区
 * FileReader(File file)			创建一个新的 FileReader ，给定要读取的File对象
 * FileReader(String fileName)		创建一个新的 FileReader ，给定要读取的文件的名称
 *  
 * read()					每次可以读取一个字符的数据，提升为int类型，读取到文件末尾，返回 -1
 * read(char[] cbuf)		每次读取b的长度个字符到数组中，返回读取到的有效字符个数， 读取到末尾时，返回 -1
 *  
 *  
 *  
 * Writer			字符输出流
 * java.io.Writer 抽象类是表示用于写出字符流的所有类的超类，将指定的字符信息写出到目的地
 * void write(int c)									写入单个字符
 * void write(char[] cbuf)								写入字符数组
 * abstract void write(char[] cbuf, int off, int len)	写入字符数组的某一部分,off数组的开始索引,len 写的字符个数
 * void write(String str)								写入字符串
 * void write(String str, int off, int len)				写入字符串的某一部分,off字符串的开始索引,len写的字符个 数
 * void flush()											刷新该流的缓冲
 * void close()											关闭此流，但要先刷新它
 * 
 * 
 * 
 * FileWriter类
 * java.io.FileWriter 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区
 * FileWriter(File file)			创建一个新的 FileWriter，给定要读取的File对象
 * FileWriter(String fileName)		创建一个新的 FileWriter，给定要读取的文件的名称
 *
 *
 *
 * 调用高级流的close()方法关闭流时会自动调用低级流的close()方法关闭低级流并释放相关系统资源
 * */
public class IOStreamDemo {
	public static void main(String[] args) throws IOException {
		File file = new File("src\\stream\\IOStreamDemo.java");
		File file2 = new File("D:\\test\\IOStreamDemo.java");
		FileReader fileReader = new FileReader(file);
		if(file2.isFile())		// 当文件不存在时判断为false
			System.out.println("是文件");
		else
			System.out.println("不是文件");
		File parent = new File(file2.getParent());
		if(!parent.exists())
			parent.mkdirs();
		FileWriter fileWriter = new FileWriter(file2);
//		int b;
//		while((b = fileReader.read()) != -1)
//			System.out.print((char)b);
		char[] buf = new char[1024];
		int len = 0;
		while((len = fileReader.read(buf)) != -1) {
			System.out.print(new String(buf, 0, len));
			fileWriter.write(buf, 0, len);
		}
		fileWriter.close();
		fileReader.close();

		File file3 = new File("D:\\test\\IOStreamDemoTTT.java");
		InputStream iStream = new FileInputStream(file);
		OutputStream oStream = new FileOutputStream(file3);
		byte[] buf2 = new byte[1024];
		while((len = iStream.read(buf2)) != -1)
			oStream.write(buf2, 0, len);
		oStream.close();
		iStream.close();

		FileOutputStream fos = new FileOutputStream("files/ttt.ttt");		// 文件后缀名可任意
		fos.write("文件后缀名可任意\n".getBytes());
		fos.write(3);	// 写入int值对应的二进制的“低八位”
		fos.flush();
		fos.close();
	}
}
